#include "viml/builtin_dict.h"
#include "viml/builtin_list.h"
#include "viml/value.h"
#include "viml/vm.h"
#include <algorithm>
#include <stdexcept>
#include <cmath>

namespace viml {

// keys(dict) 函数实现
Value keys_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() != 1) {
        throw std::runtime_error("keys() requires exactly 1 argument");
    }
    
    // 检查参数类型
    if (!args[0].is_dict()) {
        throw std::runtime_error("First argument to keys() must be a dict");
    }
    
    // 获取字典引用
    const auto& dict = args[0].as_dict();
    
    // 创建结果列表
    Value result_list = Value::list();
    auto& list_elements = result_list.as_list();
    
    // 添加所有键到列表中
    for (const auto& pair : dict) {
        list_elements.push_back(Value::string(pair.first));
    }
    
    return result_list;
}

// values(dict) 函数实现
Value values_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() != 1) {
        throw std::runtime_error("values() requires exactly 1 argument");
    }
    
    // 检查参数类型
    if (!args[0].is_dict()) {
        throw std::runtime_error("First argument to values() must be a dict");
    }
    
    // 获取字典引用
    const auto& dict = args[0].as_dict();
    
    // 创建结果列表
    Value result_list = Value::list();
    auto& list_elements = result_list.as_list();
    
    // 添加所有值到列表中
    for (const auto& pair : dict) {
        list_elements.push_back(pair.second);
    }
    
    return result_list;
}

// items(dict) 函数实现
Value items_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() != 1) {
        throw std::runtime_error("items() requires exactly 1 argument");
    }
    
    // 检查参数类型
    if (!args[0].is_dict()) {
        throw std::runtime_error("First argument to items() must be a dict");
    }
    
    // 获取字典引用
    const auto& dict = args[0].as_dict();
    
    // 创建结果列表
    Value result_list = Value::list();
    auto& list_elements = result_list.as_list();
    
    // 添加所有键值对到列表中，每个元素是[key, value]的列表
    for (const auto& pair : dict) {
        Value key_value_list = Value::list();
        auto& kv_elements = key_value_list.as_list();
        kv_elements.push_back(Value::string(pair.first));
        kv_elements.push_back(pair.second);
        list_elements.push_back(key_value_list);
    }
    
    return result_list;
}

// has_key(dict, key) 函数实现
Value has_key_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() != 2) {
        throw std::runtime_error("has_key() requires exactly 2 arguments");
    }
    
    // 检查第一个参数是否为字典
    if (!args[0].is_dict()) {
        throw std::runtime_error("First argument to has_key() must be a dict");
    }
    
    // 检查第二个参数是否为字符串
    if (!args[1].is_string()) {
        throw std::runtime_error("Second argument to has_key() must be a string");
    }
    
    // 获取字典和键
    const auto& dict = args[0].as_dict();
    const std::string& key = args[1].as_string();
    
    // 检查键是否存在
    bool exists = dict.find(key) != dict.end();
    
    return Value::boolean(exists);
}

// len(dict) 函数实现
Value len_dict_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() != 1) {
        throw std::runtime_error("len() requires exactly 1 argument");
    }
    
    // 检查参数类型
    if (!args[0].is_dict()) {
        throw std::runtime_error("len() argument must be a dict");
    }
    
    // 返回字典大小
    return Value::make_number(static_cast<int64_t>(args[0].as_dict().size()));
}

// get(dict, key, [default]) 函数实现
Value get_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() < 2 || args.size() > 3) {
        throw std::runtime_error("get() requires 2 or 3 arguments");
    }
    
    // 检查第一个参数是否为字典
    if (!args[0].is_dict()) {
        throw std::runtime_error("First argument to get() must be a dict");
    }
    
    // 检查第二个参数是否为字符串
    if (!args[1].is_string()) {
        throw std::runtime_error("Second argument to get() must be a string");
    }
    
    // 获取字典和键
    const auto& dict = args[0].as_dict();
    const std::string& key = args[1].as_string();
    
    // 查找键
    auto it = dict.find(key);
    if (it != dict.end()) {
        // 键存在，返回对应的值
        return it->second;
    } else {
        // 键不存在
        if (args.size() == 3) {
            // 返回默认值
            return args[2];
        } else {
            // 返回nil
            return Value::nil();
        }
    }
}

// remove(dict, key) 函数实现
Value remove_dict_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() != 2) {
        throw std::runtime_error("remove() requires exactly 2 arguments");
    }
    
    // 检查第一个参数是否为字典
    if (!args[0].is_dict()) {
        throw std::runtime_error("First argument to remove() must be a dict");
    }
    
    // 检查第二个参数是否为字符串
    if (!args[1].is_string()) {
        throw std::runtime_error("Second argument to remove() must be a string");
    }
    
    // 获取字典引用
    Value& dict_ref = const_cast<Value&>(args[0]);
    auto& mutable_dict = dict_ref.as_dict();
    
    // 获取键
    const std::string& key = args[1].as_string();
    
    // 查找键
    auto it = mutable_dict.find(key);
    if (it != mutable_dict.end()) {
        // 键存在，保存值并删除键值对
        Value removed_value = it->second;
        mutable_dict.erase(it);
        return removed_value;
    } else {
        // 键不存在，抛出异常
        throw std::runtime_error("Key not found in dict");
    }
}

// copy(dict) 函数实现
Value copy_dict_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() != 1) {
        throw std::runtime_error("copy() requires exactly 1 argument");
    }
    
    // 检查参数是否为字典
    if (!args[0].is_dict()) {
        throw std::runtime_error("First argument to copy() must be a dict");
    }
    
    // 获取原始字典
    const auto& original_dict = args[0].as_dict();
    
    // 创建新字典（浅拷贝）
    Value new_dict = Value::dict();
    auto& new_entries = new_dict.as_dict();
    
    // 复制所有键值对（浅拷贝）
    for (const auto& pair : original_dict) {
        new_entries[pair.first] = pair.second;
    }
    
    return new_dict;
}

// deepcopy(dict) 函数实现
Value deepcopy_dict_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() != 1) {
        throw std::runtime_error("deepcopy() requires exactly 1 argument");
    }
    
    // 检查参数是否为字典
    if (!args[0].is_dict()) {
        throw std::runtime_error("First argument to deepcopy() must be a dict");
    }
    
    // 获取原始字典
    const auto& original_dict = args[0].as_dict();
    
    // 创建新字典
    Value new_dict = Value::dict();
    auto& new_entries = new_dict.as_dict();
    
    // 递归深拷贝所有键值对
    for (const auto& pair : original_dict) {
        const Value& value = pair.second;
        if (value.is_list()) {
            // 递归深拷贝列表
            std::vector<Value> arg_vec = {value};
            new_entries[pair.first] = deepcopy_builtin(arg_vec);
        } else if (value.is_dict()) {
            // 递归深拷贝字典
            std::vector<Value> arg_vec = {value};
            new_entries[pair.first] = deepcopy_dict_builtin(arg_vec);
        } else {
            // 基本类型直接复制
            new_entries[pair.first] = value;
        }
    }
    
    return new_dict;
}

} // namespace viml